#include "Human.h"
#include "Decision.h"
#include "Utilities.h"

using namespace Hunger;

namespace Hunger
{
	Human::Human() : Animal(), morale(100), empathy(100)
	{
		reason = new Reason(this);
		this->FigurePersonalValues();
	}

	Human::~Human()
	{
		delete reason;
		reason = 0;
	}

	void Human::Speak()
	{
		std::cout << "Speaks..." << std::endl;
	}

	void Human::Move()
	{
		std::cout << "Walks along..." << std::endl;
	}

	void Human::Attack()
	{
		std::cout << "Attacks..." << std::endl;
	}

	Decision Human::Choose(Choice * choice)
	{
		return reason->Choose(choice);
	}

	std::vector<Decision> Human::Choose(std::vector<Choice *> choices)
	{
		return reason->Choose(choices);
	}

	void Human::CreateAffinities(std::vector<Human *> people)
	{
		//at the moment, the affinity a person has for another
		//is only based on likeness in values to the other - this
		//needs to have other things factored in...

		for(int person = 0; person < people.size(); person++)
		{
			Human * other = people.at(person);
			int likeness = ComparePersonalValues(other);

			affinities[other] = likeness;
		}
	}

	void Human::UpdateAffinity(Human * other, int affectedValue)
	{
		//affectedValue can be positive or negative, so
		//could change affinity either way

		int currentLikeness = affinities[other];
		currentLikeness += affectedValue;

		affinities[other] = currentLikeness;
	}

	void Human::FigurePersonalValues()
	{
		//inverse relationship
		values.spiritual = Utilities::Random(0, 100);
		values.material = 100 - values.spiritual;

		//inverse relationship
		values.social = Utilities::Random(0, 100);
		values.self = 100 - values.social;

		if(values.social > values.self)
		{
			values.family = Utilities::Random(values.self, values.social);
		}
		else if(values.self > values.social)
		{
			values.family = Utilities::Random(values.social, values.self);
		}
		else if(values.self == values.social)
		{
			values.family = 50;
		}
	}

	int Human::ComparePersonalValues(Human * other)
	{
		Values otherValues = other->GetPersonalValues();

		int spiritualLikeness, socialLikeness, difference;

		if(otherValues.spiritual > values.spiritual)
		{
			difference = otherValues.spiritual - values.spiritual;
		}
		else if(values.spiritual > otherValues.spiritual)
		{
			difference = values.spiritual - otherValues.spiritual;
		}
		else if(values.spiritual == otherValues.spiritual)
		{
			difference = 0;
		}
		spiritualLikeness = 100 - difference;

		if(otherValues.social > values.social)
		{
			difference = otherValues.social - values.social;
		}
		else if(values.social > otherValues.social)
		{
			difference = values.social - otherValues.social;
		}
		else if(values.social == otherValues.social)
		{
			difference = 0;
		}
		socialLikeness = 100 - difference;

		float average = (float)(spiritualLikeness + socialLikeness) / 2.0f;
		int totalLikeness = (int)average;

		return totalLikeness;
	}
}